/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 * 
 * This software is published under the terms of Open Source License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.
 */

package jdbcmanager.tree;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;

import jdbcmanager.dbtools.datatypes.*;
import jdbcmanager.swing.*;

/**
 * Parent class for all Node* classes.
 * <p>
 * This class contains
 * 
 * @author Francisco Morero Peyrona
 */

abstract class JdbcTreeNode extends DefaultMutableTreeNode
{
	protected static boolean   bIconsLoaded = false;
	protected static ImageIcon icon_tree_server;
	protected static ImageIcon icon_tree_catalog;
	protected static ImageIcon icon_tree_schema;
	protected static ImageIcon icon_tree_diagram;
	protected static ImageIcon icon_tree_procedure;
	protected static ImageIcon icon_tree_table_node;
	protected static ImageIcon icon_tree_table;
	protected static ImageIcon icon_tree_udt;

	protected DbEntityDescriptor ded	  = null;
	protected boolean			 bWasInit = false;

	private ImageIcon icon = null;
	
	private boolean bNewable     = true;
	private boolean bOpenable    = true;
	private boolean bEditable    = true;
	private boolean bDeleteable  = true;
	private boolean bRefreshable = true;
	private boolean bInfoable    = true;

	//-------------------------------------------------------------------------//

	JdbcTreeNode( ImageIcon icon, DbEntityDescriptor ded )
	{
		super( ded.getName() );

		if( ! bIconsLoaded )
			loadIcons();

		// This is a trick because the first time this constructor is invoked,
		// the icons are null and the icon passed as parementer is null.
		// But I know that the first node that calls here is the root node.
		this.icon = (icon == null ? icon_tree_server : icon);

		this.ded = ded;
	}

	ImageIcon getIcon()
	{
		return this.icon;
	}
	String getName()
	{
		return this.ded.getName();
	}
	String getSchema()
	{
		return this.ded.getSchema();
	}
	String getCatalog()
	{
		return this.ded.getCatalog();
	}

	void setName( String s )
	{
		this.ded.setName( s );
		setUserObject( s );
	}

	boolean isDeleteable()
	{
		return this.bDeleteable;
	}
	void setDeleteable( boolean deleteable )
	{
		this.bDeleteable = deleteable;
	}
	boolean isEditable()
	{
		return this.bEditable;
	}
	void setEditable( boolean editable )
	{
		this.bEditable = editable;
	}
	boolean isInfoable()
	{
		return this.bInfoable;
	}
	void setInfoable( boolean infoable )
	{
		this.bInfoable = infoable;
	}
	boolean isNewable()
	{
		return this.bNewable;
	}
	void setNewable( boolean newable )
	{
		this.bNewable = newable;
	}
	boolean isOpenable()
	{
		return this.bOpenable;
	}
	void setOpenable( boolean openable )
	{
		this.bOpenable = openable;
	}
	boolean isRefreshable()
	{
		return this.bRefreshable;
	}
	void setRefreshable( boolean refreshable )
	{
		this.bRefreshable = refreshable;
	}
	
	/**
	 * @param actions
	 */
	final void setValidActions( JActionSet actions )
	{		
		actions.getActionByName( "New"         ).setEnabled( isNewable()     );
		actions.getActionByName( "Open"        ).setEnabled( isOpenable()    );
        actions.getActionByName( "Edit"        ).setEnabled( isEditable()    );
        actions.getActionByName( "Rename"      ).setEnabled( isEditable()    );
        actions.getActionByName( "Delete"      ).setEnabled( isDeleteable()  );
        actions.getActionByName( "Refresh"     ).setEnabled( isRefreshable() );
        actions.getActionByName( "Information" ).setEnabled( isInfoable()    );
	}
		
	/**
	 * If Tree.refresh( node ) is invoked, this.bWasInit hast to be sat to false, in this way, its childs can be reloaded, because
	 * this.isInitialised() will return false for those nodes that will needed to be reloaded.
	 */
	public void removeAllChildren()
	{
		super.removeAllChildren();

		setInitialised( false );
	}

	void setInitialised( boolean bInit )
	{
		this.bWasInit = bInit;
	}

	/** Indicates if node needs to be initialised or not */
	abstract boolean isInitialised();
	/** Create new node. @return <code>true</code> if Tree has to be refreshed starting at selected node */
	abstract boolean new_();
	/** Open highlighted node. */
	abstract void open();
	/** Edit highlighted node. @return <code>true</code> if Tree has to be refreshed starting at selected node */
	abstract boolean edit();
	/** Rename highlighted node. @param sNewName the new node's name */
	abstract boolean rename( String sNewName );
	/** Delete highlighted node. @return <code>true</code> if Tree has to be refreshed starting at selected node */
	abstract boolean delete();
	/** Shows dialog with inofrmaiton about highlighted node */
	abstract void info();

	private void loadIcons()
	{
		JdbcTreeNode.icon_tree_server     = new ImageIcon( getClass().getResource( "images/tree_server.gif"     ) );
		JdbcTreeNode.icon_tree_catalog    = new ImageIcon( getClass().getResource( "images/tree_catalog.gif"    ) );
		JdbcTreeNode.icon_tree_schema     = new ImageIcon( getClass().getResource( "images/tree_schema.gif"     ) );
		JdbcTreeNode.icon_tree_diagram    = new ImageIcon( getClass().getResource( "images/tree_diagram.gif"    ) );
		JdbcTreeNode.icon_tree_procedure  = new ImageIcon( getClass().getResource( "images/tree_procedure.gif"  ) );
		JdbcTreeNode.icon_tree_table_node = new ImageIcon( getClass().getResource( "images/tree_table_node.gif" ) );
		JdbcTreeNode.icon_tree_table      = new ImageIcon( getClass().getResource( "images/tree_table.gif"      ) );
		JdbcTreeNode.icon_tree_udt        = new ImageIcon( getClass().getResource( "images/tree_udt.gif"        ) );

		JdbcTreeNode.bIconsLoaded = true;
	}
}